package challengeGUI;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

import javax.swing.Timer;

import control.SimpleTimer;

import animation.Animator;
import challengesManager.ChallengeManager;
import elements.GameCharacter;
import elements.GameElement;

public class CharacterSearchGUI extends ChallengeGUI {
	private static final int DEFAULT_CHARSHOW = 2000; 
	private Timer timer;
	private final int minChar = 8;
	/**
	 * a value between 5 and 10
	 */
	private int maxUpdates = 8;
	private Random random;

	private Animator animator;
	/**
	 * A array of random chars
	 */
	private GameCharacter gameChar[];
	private GameCharacter act = null;
	private GameCharacter toSearchChar = null;
	private boolean intro = true;
	/**
	 * The character which we are looking for
	 */
	private char c;

	public CharacterSearchGUI(ChallengeManager manager) {
		super(manager);

		random = new Random(System.currentTimeMillis());
		timer = new Timer(DEFAULT_UPDATE, new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				CharacterSearchGUI.this.update();
			}
		});
		timer.setDelay(DEFAULT_UPDATE);

		this.setBackground(Color.WHITE);

		animator = new Animator(this);
		animator.setBouncing(true);
		animator.setForegroundPainting(true);
	}

	@Override
	public void newRound() {
		manager.disableBuzzing();
		this.intro = true;
		timer.restart();

		animator.stop();
		animator.clear();

		this.c = GameCharacter.getRandomChar();
		this.repaint();
		//printChar();


		SimpleTimer.pause(DEFAULT_CHARSHOW, new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				CharacterSearchGUI.this.intro = false;
				maxUpdates = 5 + random.nextInt(3);

				initAnimator();

				animator.start();

				manager.enableBuzzing();

			}
		});

	}

	@Override
	public void freeze() {
		animator.stop();
	}

	@Override
	public void unfreeze() {
		animator.start();

	}

	@Override
	public void reveal(final int info) {
		animator.stop();
		timer.stop();

		GameElement chars[] = animator.getElements();
		for(GameElement e : chars) {
			if(e != act)
				e.fadeOut(true);
		} animator.start();

		//		SimpleTimer.pause(animator, 2000);
		SimpleTimer.pause(2000, new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				// Right or false?
				animator.setRightOrWrong(((info==-1)?wrong:right), CharacterSearchGUI.this.getWidth()/2, CharacterSearchGUI.this.getHeight()/2);
			}
		});

		// Right or false?
		//		animator.setRightOrWrong(((info==-1)?wrong:right), CharacterSearchGUI.this.getWidth()/2, CharacterSearchGUI.this.getHeight()/2);

		//		SimpleTimer.pause(animator, 1000);
		//		animator.clear();

		SimpleTimer.pause(3000, new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				animator.stop();
				animator.clear();
				CharacterSearchGUI.this.manager.animationOver();
			}
		});
	}

	@Override
	public void end() {
		animator.stop();
	}

	public void update() {
		String s;

		// Resets the old correct element
		if(act != null) {
			act.setString("" + GameCharacter.getRandomChar(c));
			act = null;
		}

		// Will reveal the true char in 1/5 of all cases or if the maximal number of updates were done 
		if(maxUpdates == 0 || random.nextInt(4) == 0) {
			s = "" + c;

			act = gameChar[random.nextInt(gameChar.length - 1)];
			act.setString(s);
			manager.perfectBuzzMoment(true);
			if(maxUpdates == -1) manager.animationOver();
		} else {
			s = "" + GameCharacter.getRandomChar(c);
			gameChar[random.nextInt(gameChar.length)].setString(s);
			manager.perfectBuzzMoment(false);
		}

		--maxUpdates;
	}

//	private void printChar() {
//		this.intro = true;
//		Graphics g = this.getGraphics();
//
//		g.setColor(Color.BLACK);
//		g.fillRect(0, 0, this.getWidth(), this.getHeight());
//
//		this.toSearchChar = new GameCharacter(GameElement.NO_MOVEMENT, scaler, "" + c);
//		toSearchChar.setFontSize(100);
//		toSearchChar.calcSize(g);
//
//		toSearchChar.setXY(myDim.width/2 - toSearchChar.getWidth()/2, myDim.height/2 - toSearchChar.getHeight()/2);
//		toSearchChar.setColor(Color.RED);
//		toSearchChar.paint(g);
//
//		//SimpleTimer.pause(DEFAULT_CHARSHOW);
//	}

	@Override
	public void paint(Graphics g) {
		if(!intro){
			toSearchChar = new GameCharacter(GameElement.NO_MOVEMENT,scaler, "" + c);
			toSearchChar.setColor(Color.DARK_GRAY);
			toSearchChar.setFontSize(50);
			toSearchChar.setXY(10, 10);
		}else{
			g.setColor(Color.BLACK);
			g.fillRect(0, 0, this.getWidth(), this.getHeight());

			toSearchChar = new GameCharacter(GameElement.NO_MOVEMENT, scaler, "" + c);
			toSearchChar.setFontSize(100);
			toSearchChar.calcSize(g);

			toSearchChar.setXY(myDim.width/2 - toSearchChar.getWidth()/2, myDim.height/2 - toSearchChar.getHeight()/2);
			toSearchChar.setColor(Color.RED);
		}
		toSearchChar.paint(g);
	}

	private void initAnimator() {
		gameChar = new GameCharacter[minChar + random.nextInt(5)];
		// Initalise the elements
		for(int i = 0; i<gameChar.length; i++) {
			Animator.factory.setRandomSpeed(1 + random.nextInt(3));

			// Make it possible that the char also appears in the first amount of chars
			String s;
			boolean setAct = false;

			if(i == 0) {
				s = "" + GameCharacter.getRandomChar();

				// Logical check for the manager
				setAct = (s.charAt(0) == c);
				if(setAct) manager.perfectBuzzMoment(true);
			} else {
				s = "" + GameCharacter.getRandomChar(c);
			}

			gameChar[i] = Animator.factory.newGameCharacter(Animator.factory.newRandomMover(), scaler, s);
			gameChar[i].setFontSize(40);
			gameChar[i].setRandomColor();
			gameChar[i].setRandomPosition(myDim.width, myDim.height);

			// Necessary for a reset of the element
			if(setAct && i == 0) act = gameChar[0];

			animator.add(gameChar[i]);
		}
	}

}
